import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';
import 'package:synchronized/synchronized.dart';

class LogFileOutput extends LogOutput {
  // 单例实例
  static final LogFileOutput _instance = LogFileOutput._internal();

  // 工厂构造函数返回单例
  factory LogFileOutput() {
    return _instance;
  }

  // 私有构造函数
  LogFileOutput._internal();

  final String _logDirName = 'logs';
  final int _maxFileSize = 1024 * 1024 * 10; // 10MB
  final Duration _flushInterval = Duration(seconds: 5);
  final String _singleLogFileName = 'app.log';

  late Directory _logDir;
  late RandomAccessFile _currentFile;
  late String _currentFilePath;
  DateTime? _fileStartTime;
  DateTime? _fileEndTime;

  final _lock = Lock();
  final _buffer = StringBuffer();
  Timer? _flushTimer;
  bool _isInitialized = false;

  /// 初始化日志目录和文件
  @override
  Future<void> init() async {
    try {
      if (_isInitialized) return;

      final appDocDir = await getApplicationDocumentsDirectory();
      _logDir = Directory('${appDocDir.path}/$_logDirName');

      if (!await _logDir.exists()) {
        await _logDir.create(recursive: true);
      }

      await _rotateLogFile();
      _startFlushTimer();
      _isInitialized = true;
    } catch (e) {
      debugPrint('Failed to initialize FileOutput: $e');
      rethrow;
    }
  }

  /// 格式化时间戳为文件名友好格式
  String _formatDateTime(DateTime dateTime) {
    return dateTime.toIso8601String().replaceAll(':', '-').replaceAll('.', '-');
  }

  /// 创建新的日志文件
  Future<void> _rotateLogFile() async {
    await _lock.synchronized(() async {
      // 关闭并归档旧文件（带时间戳），避免数据丢失
      if (_isInitialized) {
        _fileEndTime = DateTime.now();
        await _renameCurrentFileWithEndTime();
        await _currentFile.close();
      }

      // 创建/覆写单一日志文件
      _fileStartTime = DateTime.now();
      _currentFilePath = '${_logDir.path}/$_singleLogFileName';
      _currentFile = await File(_currentFilePath).open(mode: FileMode.write);
    });
  }

  /// 重命名当前文件以包含结束时间
  Future<void> _renameCurrentFileWithEndTime() async {
    if (_fileStartTime == null || _fileEndTime == null) return;

    final oldFile = File(_currentFilePath);
    if (await oldFile.exists()) {
      final newFileName =
          '${_formatDateTime(_fileStartTime!)}_${_formatDateTime(_fileEndTime!)}.log';
      final newFilePath = '${_logDir.path}/$newFileName';
      await oldFile.rename(newFilePath);
    }
  }

  /// 检查文件大小并决定是否滚动
  Future<void> _checkFileSize() async {
    try {
      final length = await _currentFile.length();
      if (length >= _maxFileSize) {
        await _rotateLogFile();
      }
    } catch (e) {
      debugPrint('Failed to check file size: $e');
      await _rotateLogFile();
    }
  }

  /// 启动定时刷新缓冲区
  void _startFlushTimer() {
    _flushTimer = Timer.periodic(_flushInterval, (_) => _flushBuffer());
  }

  /// 写入缓冲区
  @override
  void output(OutputEvent event) {
    if (!_isInitialized) return;

    _lock.synchronized(() {
      _buffer.writeln(event.lines.join('\n'));
    });
  }

  /// 刷新缓冲区到文件
  Future<void> _flushBuffer() async {
    if (_buffer.isEmpty) return;

    await _lock.synchronized(() async {
      if (_buffer.isEmpty) return;

      try {
        await _checkFileSize();
        await _currentFile.writeString(_buffer.toString());
        _buffer.clear();
        await _currentFile.flush();
      } catch (e) {
        debugPrint('Failed to write log to file: $e');
        await _rotateLogFile();
        try {
          await _currentFile.writeString(_buffer.toString());
          _buffer.clear();
          await _currentFile.flush();
        } catch (e) {
          debugPrint('Retry write failed: $e');
        }
      }
    });
  }

  /// 确保所有日志都已写入文件
  Future<void> ensureAllWritten() async {
    // _flushTimer?.cancel();
    await _flushBuffer();
    if (_isInitialized) {
      // try {
      //   _fileEndTime = DateTime.now();
      //   await _renameCurrentFileWithEndTime();
      //   await _currentFile.close();
      // } catch (e) {
      //   debugPrint('Failed to close log file: $e');
      // }
    }
  }

  @override
  Future<void> destroy() async {
    _flushTimer?.cancel();
    await ensureAllWritten();
  }

  /// 获取当前正在写入的日志文件路径（可能是 pending 的文件名）
  String? getCurrentLogPath() {
    if (!_isInitialized) return null;
    return _currentFilePath;
  }

  /// 获取最新生成的日志文件（含结束时间的文件）路径
  Future<String?> getLatestCompletedLogPath() async {
    if (!_isInitialized) return null;
    try {
      final files = await _logDir
          .list()
          .where((e) => e is File && e.path.endsWith('.log'))
          .toList();
      if (files.isEmpty) return null;
      files.sort((a, b) => b.statSync().modified.compareTo(a.statSync().modified));
      return files.first.path;
    } catch (e) {
      debugPrint('Failed to get latest log file: $e');
      return null;
    }
  }
}
